﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;

namespace LightWadf.Core.Filter
{
    /// <summary>
    /// <para>该过滤器将会把处理方法的结果进行缓存</para>
    /// <para>当收到请求时，如果存在缓存，会用缓存数据直接返回</para>
    /// <para>默认滑动缓存 5 分钟</para>
    /// <para>该过滤器适合结果不会随着 <see cref="System.Web.HttpContext.Request.Path"/> 的改变而变化的处理方法</para>
    /// </summary>
    public class CacheFilter : IFilter
    {
        private MemoryCacheEntryOptions options = new MemoryCacheEntryOptions();
        private static IMemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
        private Dictionary<string, bool> cacheDataExisted = new Dictionary<string, bool>();

        /// <summary>
        /// 默认滑动缓存 5 分钟
        /// </summary>
        public CacheFilter() : this(new TimeSpan(0, 5, 0))
        {
        }

        /// <summary>
        /// 用绝对过期时间初始化
        /// </summary>
        /// <param name="offset"></param>
        public CacheFilter(DateTimeOffset offset)
        {
            this.options.AbsoluteExpiration = offset;
        }

        /// <summary>
        /// 用滑动过期时间初始化
        /// </summary>
        /// <param name="time"></param>
        public CacheFilter(TimeSpan time)
        {
            this.options.SlidingExpiration = time;
        }

        public override object BeforeProcess(HttpContext context)
        {
            string key = context.Request.Path;
            object result = Cache.Get(key);
            if(result != null)
            {
                this.cacheDataExisted[key] = true;
            }
            else
            {
                this.cacheDataExisted[key] = false;
            }
            return result;
        }

        public override void AfterProcess(HttpContext context, ref object result)
        {
            string key = context.Request.Path;
            if (!this.cacheDataExisted[key])
            {
                Cache.Set<object>(key, result);
            }
        }
    }
}
